/**
 * 
 */
package org.pexx.components.jtable;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;



/**
 * 
 */
public class SqlResultTableModel extends DynamicTableModel {
	
	//private int numRows = 0;
	private int numColumns = 0;
	
	private Class<?> [] columnClasses = null;
	private String[] columnNames = null;
	private String[] columnNameReplacement = null;
	
	/**
	 * 
	 */
	public SqlResultTableModel() {
		super();
	}
		
	/**
	 * @param columnNameReplacement the columnNameReplacement to set
	 */
	public void setColumnNameReplacement(String[] columnNameReplacement) {

		this.columnNameReplacement = columnNameReplacement;
	}
	
	public void setResultSet(ResultSet resultSet, String[] columnNameReplacement) throws SQLException {
		setColumnNameReplacement(columnNameReplacement);
		setResultSet(resultSet);
	}
	
	/**
	 * @param resultSet the resultSet to set
	 * @throws SQLException 
	 */
	public void setResultSet(ResultSet resultSet) throws SQLException {
		
		
		clear();
		
		//numRows = 0;
		numColumns = 0;
				
		if (resultSet == null)
			return;
		
		ResultSetMetaData meta = resultSet.getMetaData();
		
		numColumns = meta.getColumnCount();
				
		Class<?> [] cClasses = createClasses(meta);
		String[] cNames = createColumnNames(meta);

		if (hasMetaChanged (cClasses, cNames)) {
			
			columnClasses = cClasses;
			columnNames = cNames;
			
			setTableMeta(cNames, cClasses);					
		}		
		
		addResults (resultSet) ;
		
	}
	
	/**
	 * @param cClasses
	 * @param cNames
	 * @return
	 */
	private boolean hasMetaChanged(Class<?>[] cClasses, String[] cNames) {

		if ((columnClasses == null) || (columnClasses.length != cClasses.length))
			return true;
		
		if ((columnNames == null) || (columnNames.length != cNames.length))
			return true;
		
		int o = cClasses.length-1;
		
		for (int i = o; i >= 0; i--)
			if (!columnClasses[i].equals(cClasses[i]))
				return true;
		
		for (int i = o; i >= 0; i--)
			if (!columnNames[i].equals(cNames[i]))
				return true;		
		
		return false;
	}

	private String[] createColumnNames (ResultSetMetaData meta) throws SQLException {
		
		int numColumns = meta.getColumnCount();
		
		String[] names = new String[numColumns];
		
		for (int i = 0; i < numColumns; i++) {
			
			if ((columnNameReplacement != null) && (i < columnNameReplacement.length))
				names[i] = columnNameReplacement[i];
			else
				names[i] = meta.getColumnName(i+1);
		}
		
		return names;
	}
	
	private Class<?>[] createClasses (ResultSetMetaData meta) throws SQLException {
		
		int numColumns = meta.getColumnCount();
		
		Class<?>[] classes = new Class<?>[numColumns];
		
		for (int i = 0; i < numColumns; i++) {
			try {
				classes[i] = Class.forName(meta.getColumnClassName(i+1));
			} catch (Exception e) {
				
				System.out.println("Class not found for " + meta.getColumnClassName(i+1));
				
				
				classes[i] = String.class;
			}
		}
		
		return classes;
	}
	

	/**
	 * @param resultSet2
	 * @throws SQLException 
	 */
	private void addResults(ResultSet resultSet) throws SQLException {
		
		ArrayList<Object> t;
		
		while (resultSet.next()) {
			
			
			
			t = createEmptyRow();
			
			for (int i = 0; i < numColumns; i++) 
				t.set(i, resultSet.getObject(i+1));			
			
			//numRows++;
				
		}
		
		fireTableDataChanged();
		
	}
	
	
	/**
	 * @return the numRows
	 */
	public int getNumRows() {
		return values.size();
	}
	
}
